﻿#include "TimerDialog.h"
#include "../../Settings.h"
#include "../../Forms/Client.CMain.h"

namespace S = ServerPackets;
using namespace Client::MirControls;
using namespace Client::MirGraphics;

namespace Client::MirScenes::Dialogs
{

    TimerDialog::TimerDialog() : _eggTimer(new MirAnimatedControl();
        _eggTimer->setIndex(960);
        _eggTimer->setAnimationCount(6);
        _eggTimer->setAnimationDelay(333);
        _eggTimer->setLibrary(Libraries::Prguse2);
        _eggTimer->setParent(this);
        Point tempVar(23, 0);
        _eggTimer->setLocation(&tempVar);
        _eggTimer->setNotControl(true);
        _eggTimer->setUseOffSet(true);
        _eggTimer->setAnimated(true);
        _eggTimer->setLoop(false);
        _eggTimer->setOpacity(1.0F)), _1000(new MirImageControl();
        _1000->setParent(this);
        _1000->setIndex(_libraryOffset + 0);
        _1000->setLibrary(Libraries::Prguse2);
        _1000->setNotControl(true);
        _1000->setUseOffSet(true);
        Point tempVar2(0, 70);
        _1000->setLocation(&tempVar2);
        _1000->setVisible(false)), _100(new MirImageControl();
        _100->setParent(this);
        _100->setIndex(_libraryOffset + 0);
        _100->setLibrary(Libraries::Prguse2);
        _100->setNotControl(true);
        _100->setUseOffSet(true);
        Point tempVar3(22, 70);
        _100->setLocation(&tempVar3);
        _100->setVisible(false)), _10(new MirImageControl();
        _10->setParent(this);
        _10->setIndex(_libraryOffset + 0);
        _10->setLibrary(Libraries::Prguse2);
        _10->setNotControl(true);
        _10->setUseOffSet(true);
        Point tempVar4(58, 70);
        _10->setLocation(&tempVar4);
        _10->setVisible(false)), _1(new MirImageControl();
        _1->setParent(this);
        _1->setIndex(_libraryOffset + 0);
        _1->setLibrary(Libraries::Prguse2);
        _1->setNotControl(true);
        _1->setUseOffSet(true);
        Point tempVar5(80, 70);
        _1->setLocation(&tempVar5);
        _1->setVisible(false)), _colon(new MirImageControl();
        _colon->setParent(this);
        _colon->setIndex(_libraryOffset + 10);
        _colon->setLibrary(Libraries::Prguse2);
        _colon->setNotControl(true);
        _colon->setUseOffSet(true);
        Point tempVar6(44, 70);
        _colon->setLocation(&tempVar6);
        _colon->setVisible(false))
        {
        Point tempVar7(Settings::ScreenWidth - 120, Settings::ScreenHeight - 230);
        setLocation(&tempVar7);
        setNotControl(true);
        Size tempVar8(120, 100);
        setSize(&tempVar8);
        setMovable(false);
        setSort(true);






        }

    void TimerDialog::Process()
    {
        auto timer = GetBestTimer();

        if (timer != nullptr)
        {
            if (timer != CurrentTimer || timer->Refresh)
            {
                CurrentTimer = timer;
                CurrentTimer->Refresh = false;

                _timerStarted = true;
                _timerTime = CMain::Time + 1000;
                _timerCounter = static_cast<int>(CurrentTimer->RelativeTime - (CMain::Time / 1000));

                UpdateTimeGraphic();
            }
        }

        if (CurrentTimer == nullptr || _timerStarted == false || CMain::Time < _timerTime)
        {
            return;
        }

        _timerCounter--;
        _timerTime = CMain::Time + 1000;

        if (_timerCounter < 0 && _eggTimer != nullptr)
        {
            setVisible(false);
            _colon->setVisible(false);
            _1->setVisible(_colon->getVisible());
            _10->setVisible(_1->getVisible());
            _100->setVisible(_10->getVisible());
            _1000->setVisible(_100->getVisible());
            _eggTimer->setLoop(false);
            _timerStarted = false;

            ActiveTimers.Remove(CurrentTimer);
            return;
        }

        UpdateTimeGraphic();
    }

    ClientTimer *TimerDialog::GetBestTimer()
    {
        return ActiveTimers.OrderBy([&] (std::any x)
        {
            x::RelativeTime;
        }).FirstOrDefault();
    }

    ClientTimer *TimerDialog::GetTimer(const std::string &key)
    {
        return ActiveTimers.FirstOrDefault([&] (std::any x)
        {
            return x->Key == key;
        });
    }

    void TimerDialog::AddTimer(S::SetTimer *p)
    {
        auto currentTimer = GetTimer(p->Key);

        if (currentTimer != nullptr)
        {
            currentTimer->Update(p->Seconds, p->Type);
            return;
        }

        ClientTimer tempVar(p->Key, p->Seconds, p->Type);
        ActiveTimers.push_back(&tempVar);
    }

    void TimerDialog::ExpireTimer(const std::string &key)
    {
        auto timer = ActiveTimers.FirstOrDefault([&] (std::any x)
        {
            return x->Key == key;
        });

        if (timer != nullptr)
        {
            timer->RelativeTime = 0;

            if (timer == CurrentTimer)
            {
                _timerCounter = 0;
            }
        }
    }

    void TimerDialog::UpdateTimeGraphic()
    {
        TimeSpan ts = TimeSpan(0, 0, _timerCounter);

        if (ts.Hours > 0)
        {
            _1000->setIndex(_libraryOffset + (ts.Hours / 10));
            _100->setIndex(_libraryOffset + (ts.Hours % 10));
            _10->setIndex(_libraryOffset + (ts.Minutes / 10));
            _1->setIndex(_libraryOffset + (ts.Minutes % 10));
        }
        else
        {
            _1000->setIndex(_libraryOffset + (ts.Minutes / 10));
            _100->setIndex(_libraryOffset + (ts.Minutes % 10));
            _10->setIndex(_libraryOffset + (ts.Seconds / 10));
            _1->setIndex(_libraryOffset + (ts.Seconds % 10));
        }

        setVisible(true);
        _colon->setVisible(true);
        _1->setVisible(_colon->getVisible());
        _10->setVisible(_1->getVisible());
        _100->setVisible(_10->getVisible());
        _1000->setVisible(_100->getVisible());

        switch (CurrentTimer->Type)
        {
            default:
            case 0:
                _eggTimer->setVisible(false);
                _eggTimer->setIndex(960);
                break;
            case 1:
                _eggTimer->setVisible(true);
                _eggTimer->setIndex(960);
                break;
            case 2:
                _eggTimer->setVisible(true);
                _eggTimer->setIndex(440);
                break;
        }

        _eggTimer->setLoop(true);
    }

    ClientTimer::ClientTimer(const std::string &key, int time, unsigned char type)
    {
        Key = key;
        Update(time, type);
    }

    void ClientTimer::Update(int time, unsigned char type)
    {
        Seconds = time;
        Type = type;

        RelativeTime = Seconds + (CMain::Time / 1000);
        Refresh = true;
    }
}
